package com.zlc.platform.interceptor;

import com.zlc.common.common.entity.BusinessResult;
import com.zlc.common.common.exception.BusinessException;
import com.zlc.common.common.service.ContextHolder;
import com.zlc.common.model.user.UserInfo;
import com.zlc.common.util.JsonHelper;
import com.zlc.common.util.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;

import static com.zlc.common.common.constant.PlatConstant.LoginConstant.NOW_USER;
import static com.zlc.common.common.constant.PlatformRedisConstant.MAYAN_PLATFORM_LOGIN_USER;

/**
 * 登录拦截
 * @author zl
 */
@Slf4j
@Component
public class WebInterceptor implements HandlerInterceptor {


    private static final List<String> UNCHECK_URI_LIST = Arrays.asList("error", "login", "needCheckCode", "swagger");

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws BusinessException {
        String token = request.getHeader("token");
        if (ObjectUtils.isEmpty(token)) {
            token = request.getParameter("token");
        }
        String requestUri = request.getRequestURI();
        log.info("请求的路径为：{}", requestUri);

        if (UNCHECK_URI_LIST.stream().anyMatch(requestUri::contains)) {
            return true;
        }
        String remoteAddr = request.getRemoteAddr();
        if (!"127.0.0.1".equals(remoteAddr) && !"0:0:0:0:0:0:0:1".equals(remoteAddr) && !"localhost".equals(remoteAddr)) {
            if (ObjectUtils.isEmpty(token)) {
                writeBody(response, "无权限访问");
                return false;
            }
            String value = RedisUtils.get(MAYAN_PLATFORM_LOGIN_USER + token);
            if (ObjectUtils.isEmpty(value)) {
                writeBody(response, "无权限访问");
                return false;
            }
            UserInfo info = JsonHelper.jsonToObject(value, UserInfo.class);
            ContextHolder.set(NOW_USER, info);
        } else if (!ObjectUtils.isEmpty(token)) {
            try {
                String value = RedisUtils.get(MAYAN_PLATFORM_LOGIN_USER + token);
                UserInfo info = JsonHelper.jsonToObject(value, UserInfo.class);
                ContextHolder.set(NOW_USER, info);
            } catch (Exception e) {
                writeBody(response, "无权限访问");
                e.printStackTrace();
                return false;
            }
        }
        return true;
    }

    private void writeBody(HttpServletResponse response, String msg) {
        try {
            BusinessResult exception = new BusinessResult(msg, "401", null);
            response.getOutputStream().write(JsonHelper.toJson(exception).getBytes(StandardCharsets.UTF_8));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("this is postHandle ...");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("this is afterCompletion ...");
        ContextHolder.clearContext();
    }


    private String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        // 本机访问
        if ("localhost".equalsIgnoreCase(ip) || "127.0.0.1".equalsIgnoreCase(ip) || "0:0:0:0:0:0:0:1".equalsIgnoreCase(ip)) {
            // 根据网卡取本机配置的IP
            InetAddress inet;
            try {
                inet = InetAddress.getLocalHost();
                ip = inet.getHostAddress();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }
        // 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
        if (StringUtils.isNotBlank(ip) && ip.contains(",")) {
            ip = ip.substring(0, ip.indexOf(","));
        }
        return ip;
    }

    /**
     * 获取mac地址
     */
    public static String getMacAddress() throws Exception {
        // 取mac地址
        byte[] macAddressBytes = NetworkInterface.getByInetAddress(InetAddress.getLocalHost()).getHardwareAddress();
        // 下面代码是把mac地址拼装成String
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < macAddressBytes.length; i++) {
            if (i != 0) {
                sb.append("-");
            }
            // mac[i] & 0xFF 是为了把byte转化为正整数
            String s = Integer.toHexString(macAddressBytes[i] & 0xFF);
            sb.append(s.length() == 1 ? 0 + s : s);
        }
        return sb.toString().trim().toUpperCase();
    }

}
